package com.jumper.property.comparer.diff.value;

import com.jumper.property.comparer.core.bean.PropertySetting;
import com.jumper.property.comparer.diff.Diff;
import com.jumper.property.comparer.diff.DiffVal;
import com.jumper.property.comparer.formatter.ArrayDiffBodyFormatter;
import com.jumper.property.comparer.formatter.ArrayDiffHeaderFormatter;
import com.jumper.property.comparer.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayDiff implements Diff {

    private final PropertySetting setting;
    private final Collection<?> beforeList;
    private final Collection<?> afterList;
    private final List<DiffEditRow> rows;

    public ArrayDiff(PropertySetting setting, Collection<?> beforeList, Collection<?> afterList, List<DiffEditRow> addRows, List<DiffEditRow> removeRows, List<DiffEditRow> updateRows) {
        this.setting = setting;
        this.beforeList = beforeList;
        this.afterList = afterList;
        this.rows = new ArrayList<>();
        this.rows.addAll(addRows);
        this.rows.addAll(removeRows);
        this.rows.addAll(updateRows);
    }

    @Override
    public List<DiffVal> getDiffValues() {
        List<DiffVal> diffs = new ArrayList<>();
        if (rows.size() > 0) {
            rows.forEach(row -> {
                String diffValue = getRowDiffValue(row);
                if (!StringUtils.isEmpty(diffValue)) {
                    diffs.add(new DiffVal(
                            row.getBeforeData(), row.getAfterData(), diffValue
                    ));
                }
            });
        }
        if (diffs.size() > 0) {
            diffs.add(0, new DiffVal(
                    beforeList, afterList, getDiffHeaderValue()
            ));
        }
        return diffs;
    }

    private String getRowDiffValue(DiffEditRow row) {
        return new ArrayDiffBodyFormatter(setting.getPropertyName(), row).format();
    }

    private String getDiffHeaderValue() {
        return new ArrayDiffHeaderFormatter(setting.getPropertyName()).format();
    }
}
